package com.iot.practice.designpattern.state.nopattern2;

/**
 * <p>NoStatePatternClient2 此类用于：</p>
 * <p>@author：hujm</p>
 * <p>@date：2021年03月22日 16:23</p>
 * <p>@remark：模拟电梯的动作</p>
 */
public class NoStatePatternClient2 {

    public static void main(String[] args) {
        ILift lift = new Lift();
        // 电梯的初始条件应该是停止状态
        lift.setState(ILift.STOPPING_STATE);
        // 首先是电梯门开启，人进去
        lift.open();
        // 然后电梯门关闭
        lift.close();
        // 再然后，电梯跑起来，向上或者向下
        lift.run();
        // 最后到达目的地，电梯挺下来
        lift.stop();
    }

    /**
     * 我们来想一下，这段程序有什么问题，首先 Lift.java 这个文件有点长，长的原因是我们在程序中使
     * 用了大量的 switch…case 这样的判断（if…else 也是一样），程序中只要你有这样的判断就避免不了加长
     * 程序，同步的在业务比较复杂的情况下，程序体会更长，这个就不是一个很好的习惯了，较长的方法或者
     * 类的维护性比较差，毕竟程序是给人来阅读的；其次，扩展性非常的不好，大家来想想，电梯还有两个状
     * 态没有加，是什么？通电状态和断电状态，你要是在程序再增加这两个方法， 你看看 Open()、 Close()、 Run()、
     * Stop()这四个方法都要增加判断条件，也就是说 switch 判断体中还要增加 case 项，也就说与开闭原则相
     * 违背了；再其次，我们来思考我们的业务，电梯在门敞开状态下就不能上下跑了吗？电梯有没有发生过只
     * 有运行没有停止状态呢（从 40 层直接坠到 1 层嘛）？电梯故障嘛，还有电梯在检修的时候，可以在 stop
     * 状态下不开门，这也是正常的业务需求呀，你想想看，如果加上这些判断条件，上面的程序有多少需要修
     * 改？虽然这些都是电梯的业务逻辑，但是一个类有且仅有一个原因引起类的变化，单一职责原则，看看我
     * 们的类，业务上的任务一个小小增加或改动都对我们的这个电梯类产生了修改，这是在项目开发上是有很
     * 大风险的。既然我们已经发现程序上有以上问题，我们怎么来修改呢？
     *
     * 刚刚我们是从电梯的有哪些方法以及这些方法执行的条件去分析，现在我们换个角度来看问题，我们
     * 来想电梯在具有这些状态的时候，能够做什么事情，也就是说在电梯处于一个具体状态时，我们来思考这
     * 个状态是由什么动作触发而产生以及在这个状态下电梯还能做什么事情，举个例子来说，电梯在停止状态
     * 时，我们来思考两个问题：
     * 第一、这个停止状态时怎么来的，那当然是由于电梯执行了 stop 方法而来的；
     * 第二、在停止状态下，电梯还能做什么动作?继续运行？开门？那当然都可以了。
     * 我们再来分析其他三个状态，也都是一样的结果，我们只要实现电梯在一个状态下的两个任务模型就
     * 可以了：这个状态是如何产生的以及在这个状态下还能做什么其他动作（也就是这个状态怎么过渡到其他
     * 状态），既然我们以状态为参考模型，那我们就先定义电梯的状态接口
     */
}
